package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.constants.MQConstants;
import com.heima.common.dtos.AppHttpCodeEnum;
import com.heima.common.dtos.PageResponseResult;
import com.heima.common.dtos.ResponseResult;
import com.heima.common.exception.LeadNewsException;
import com.heima.model.wemedia.dtos.WmNewsDownUpDto;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.BeanHelper;
import com.heima.utils.common.JsonUtils;
import com.heima.utils.common.ThreadLocalUtils;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import com.heima.wemedia.service.WmNewsService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 自媒体图文内容信息表 服务实现类
 * </p>
 *
 * @author QLJ
 * @since 2022-09-02
 */
@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {


    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmNewsAutoScanService wmNewsAutoScanService;

    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;


    /**
     * 自媒体文章查询
     */
    @Override
    public PageResponseResult findList(WmNewsPageReqDto dto) {
        //参数校验
        dto.checkParam();

        //判断是否登录（获取登录用户信息）
        WmUser wmUser = (WmUser) ThreadLocalUtils.get();
        if (wmUser == null) {
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }

        //分页页码以及条数
        IPage<WmNews> iPage = new Page<>(dto.getPage(), dto.getSize());
        //文章搜索条件
        QueryWrapper<WmNews> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", wmUser.getId());


        //分类id
        if (dto.getChannelId() != null) {
            wrapper.eq("channel_id", dto.getChannelId());
        }

        //关键字模糊查找
        if (dto.getKeyword() != null) {
            wrapper.like("title", dto.getKeyword());
        }

        //状态
        if (dto.getStatus() != null) {
            wrapper.eq("status", dto.getStatus());
        }

        //发布时间
        if (dto.getBeginPubDate() != null && dto.getEndPubDate() != null) {
            wrapper.between("publish_time", dto.getBeginPubDate(), dto.getEndPubDate());
        }

        //按照创建时间倒序
        wrapper.orderByDesc("created_time");

        //分页查询
        iPage = page(iPage, wrapper);

        //封装返回对象
        PageResponseResult pageResponseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) iPage.getTotal());
        pageResponseResult.setErrorMessage("操作成功");
        pageResponseResult.setCode(200);
        pageResponseResult.setData(iPage.getRecords());

        return pageResponseResult;
    }


    /**
     * 发布文章
     */
    @Override
    @Transactional
    public ResponseResult submit(WmNewsDto dto) {
        //属性拷贝创建wmNews
        WmNews wmNews = BeanHelper.copyProperties(dto, WmNews.class);

        WmUser wmUser = (WmUser) ThreadLocalUtils.get();
        Integer userId = wmUser.getId();
        if (userId == null) {
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }

        //发布人ID
        assert wmNews != null;
        wmNews.setUserId(wmUser.getId());


        //如果封面选了自动
        List<String> contentImages = null;
        if (wmNews.getType() == -1) {
            //获取文章的图片
            contentImages = getContentImagesFromWmNews(wmNews.getContent());


            //图片个数
            int size = contentImages.size();

            //无图情况
            if (size == 0) {
                wmNews.setType((short) 0);   //类型设置为无图
                wmNews.setImages(null);
            }

            //单图情况
            if (1 <= size && size <= 2) {
                wmNews.setType((short) 1);   //类型设置为单图
                wmNews.setImages(contentImages.get(0));
            }

            //多图情况
            if (3 <= size) {
                wmNews.setType((short) 3);   //类型设置为多图
                wmNews.setImages(String.join(",", contentImages.subList(0, 3)));
            }
        }


        //判断文章是否是新建
        if (wmNews.getId() == null) {
            //插入对象
            //设置创建时间
            wmNews.setCreatedTime(new Date());
            save(wmNews);
        } else {
            //编辑情况
            //删除文章关联的素材
            QueryWrapper<WmNewsMaterial> wmNewsMaterialQueryWrapper = new QueryWrapper<>();
            wmNewsMaterialQueryWrapper.eq("news_id", wmNews.getId());
            wmNewsMaterialMapper.delete(wmNewsMaterialQueryWrapper);
            updateById(wmNews);
        }

        //绑定文章和素材的关系

        //获取文章素材id
        if (CollectionUtils.isNotEmpty(contentImages)) {
            //绑定素材
            List<Integer> newsIds =  queryMaterialIdsByUrls(contentImages);
            if (CollectionUtils.isNotEmpty(newsIds)) {
                wmNewsMaterialMapper.saveNewsMaterials(newsIds,wmNews.getId(),0);
            }
        }

        //封面与素材的绑定
        String images = wmNews.getImages();
        if (StringUtils.isNotBlank(images)){
            List<String> split = Arrays.asList(images.split(","));
            List<Integer> newsIds = queryMaterialIdsByUrls(split);
            if (CollectionUtils.isNotEmpty(newsIds)) {
                wmNewsMaterialMapper.saveNewsMaterials(newsIds,wmNews.getId(),1);
            }
        }


        wmNews.setSubmitedTime(new Date());    //设置提交时间
        updateById(wmNews);

        //状态为1则提交审核
        if(dto.getStatus().equals(WmNews.Status.SUBMIT.getCode())){
            //提交审核
            wmNewsAutoScanService.autoScanWmNews(wmNews);
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 文章上下架
     */
    @Override
    public ResponseResult downOrUp(WmNewsDownUpDto dto) {
        //查询文章是否存在
        WmNews wmNews = getById(dto.getId());
        if(wmNews==null){
            throw new LeadNewsException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        //查找文章是否已发布
        if(wmNews.getStatus()!=9){
            throw new LeadNewsException(400,"请先发布文章再上下架");
        }

        //修改文章的enable值
        wmNews.setEnable(dto.getEnable());
        updateById(wmNews);

        //发送消息，同步APP端的上下架状态
        Map<String,Object> msg = new HashMap<>();
        msg.put("articleId",wmNews.getArticleId());
        msg.put("enable",dto.getEnable());
        //发送下架消息
        kafkaTemplate.send(MQConstants.WM_NEWS_UP_OR_DOWN_TOPIC,JsonUtils.toString(msg));
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    //通过图片地址查询id
    private List<Integer> queryMaterialIdsByUrls(List<String> contentImages) {
        QueryWrapper<WmMaterial> wrapper = new QueryWrapper<>();
        wrapper.in("url", contentImages);
        List<WmMaterial> wmMaterials = wmMaterialMapper.selectList(wrapper);

        ArrayList<Integer> newsIds = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(wmMaterials)){
            wmMaterials.forEach(wmMaterial -> newsIds.add(wmMaterial.getId()));
        }
        return newsIds;
    }


    //获取文章的图片
    private List<String> getContentImagesFromWmNews(String content) {
        List<String> imgList = new ArrayList<>();
        if(StringUtils.isNotBlank(content)) {
            //获取所有Map集合
            List<Map> list = JsonUtils.toList(content, Map.class);

            imgList = list.stream()
                    .filter(map->map.get("type").equals("image"))
                    .map(map->(String)map.get("value"))
                    .collect(Collectors.toList());
        }
        return imgList;
    }
}
